const util = require("../utils/connection");
const { ObjectUtil } = require("../utils/index");

module.exports = class Table {
  /**
   * 构造参数，做初始化操作
   * @param {String} tableName 表名
   * @param {{insertFilterField: string, updateFilterField: [string, string]}} [options] 其他配置信息
   * @param {Array} fields 表格的字段
   * @param {Object} [options.unique = 'id'] 表字段的唯一标示
   * @param {Array} [options.updateFilterField] 修改需要过滤的字段
   * @param {Array} [options.insertFilterField] 修改需要过滤的字段
   */
  constructor(tableName, fields, options) {
    if (!options) options = {};
    if (!tableName) throw new Error("【缺少必要参数】必须要一个合法的数据表名");
    const unique = options["unique"] || "id";
    const updateFilterField = options["updateFilterField"] || [];
    updateFilterField.unshift(unique); // 暂时不考虑主键是否自增，直接将主键的操作排除在外
    const insertFilterField = options["insertFilterField"] || [];
    updateFilterField.unshift(unique); // 暂时不考虑主键是否自增，直接将主键的操作排除在外
    this._table = {
      name: tableName,
      unique,
      fields,
      updateFilterField,
      insertFilterField
    };
  }

  get name() {
    return this._table.name;
  }

  get fields() {
    return this._table.fields;
  }

  get unique() {
    return this._table.unique;
  }
  /**
   * 新增或修改操作，会根据插入的对象字段插入数据
   *  insert: 会过滤假值，插入所有有效值字段
   *  update: 不过滤假值，插入所有有效值字段
   * 两个操作都不会把主键包含进来
   * @param {Object} element 需要插入的对象
   * @return {Promise<any>}
   */
  insertOrUpdate(element) {
    return new Promise(async (resolve, reject) => {
      if (ObjectUtil.isEmpty(element)) return reject(false);
      const connection = await util.getConnection();
      const table = this._table;
      // const keys = Object.keys(element);
      const keys = this.fields;
      const placeholder = [];
      const data = [];
      let sql = "";
      if (element[table.unique]) {
        sql = `update ${table.name} set `;
        keys.forEach(key => {
          if (table.updateFilterField.indexOf(key) === -1) {
            placeholder.push(`${key} = ?`);
            data.push(element[key]);
          }
        });
        sql += `${placeholder.join(", ")} where ${table.unique} = ?`;
        data.push(element[table.unique]);
      } else {
        const _filterKey = [];
        keys.forEach(key => {
          if (
            !(!element[key] && element[key] !== 0) &&
            table.insertFilterField.indexOf(key) === -1
          ) {
            placeholder.push("?");
            _filterKey.push(key);
            data.push(`${element[key]}`);
          }
        });
        sql = `insert into ${table.name} (${_filterKey.join(", ")})
                   values (${placeholder.join(", ")})`;
      }
      connection.query(sql, data, function(error, results) {
        connection.release();
        if (error) {
          console.error("执行SQL异常：", error.message);
          return reject(error);
        }
        resolve({ id: results.insertId });
      });
    });
  }
};
